const GoodsDAO = require("../dao/GoodsDAO");
const DAO = require("../dao/DAO");
const GoodsAttributeDAO = require("../dao/GoodAttributeDAO");
const orm = require("orm");
const { map, omit, clone } = require("lodash");
const path = require("path");
const { keyBy, forEach } = require("lodash");
//商品列表
module.exports.getGoods = function (params, cb) {
  const { query, pagesize, pagenum } = params;
  if (!pagenum) return cb("pagenum 参数不合法");
  if (!pagesize) return cb("pagenum 参数不合法");
  const conditions = {};
  conditions["columns"] = {};
  if (query) {
    conditions["columns"]["goods_name"] = orm.like("%" + query + "%");
  }
  conditions["columns"]["is_del"] = "0";
  GoodsDAO.countByKey(conditions, function (err, count) {
    if (err) return cb(err);
    let offset = (pagesize - 1) * pagenum;
    if (offset > count) {
      offset = count;
    }
    conditions["offset"] = offset;
    conditions["limit"] = Number(pagesize);
    //only 以外查询的 显示上有返回对应列，实际数据为null
    conditions["only"] = [
      "goods_id",
      "goods_name",
      "goods_price",
      "goods_weight",
      "goods_state",
      "add_time",
      "goods_number",
      "upd_time",
      "hot_mumber",
      "is_promote",
    ];
    conditions["order"] = "-add_time";

    GoodsDAO.findByKey(conditions, function (err, goodList) {
      if (err) return cb(err);
      let resultData = {};
      resultData["total"] = count;
      resultData["pagenum"] = pagenum;
      resultData["goodList"] = map(goodList, function (good) {
        return omit(
          good,
          "goods_introduce",
          "is_del",
          "goods_big_logo",
          "goods_small_logo",
          "delete_time"
        );
      });
      cb(err, resultData);
    });
  });
};

//商品基本信息 校验
function generateGoodInfo(params) {
  return new Promise(function (resolve, reject) {
    let info = {},
      {
        goods_id,
        goods_name,
        goods_price,
        goods_number,
        goods_cat,
        goods_weight,
        goods_introduce,
        goods_big_logo,
        goods_small_logo,
        goods_state,
        hot_mumber,
        attrs,
        pics,
      } = params;
    if (goods_id) info["goods_id"] = goods_id;
    if (!goods_name) return reject("商品名称不能为空");
    info["goods_name"] = goods_name;

    if (!goods_price) return reject("商品价格不能为空");
    let price = parseFloat(goods_price);
    if (isNaN(price) || price < 0) return reject("商品价格不正确");
    info["goods_price"] = price;

    if (!goods_number) return reject("商品数量不能为空");
    var num = parseInt(goods_number);
    if (isNaN(num) || num < 0) return reject("商品数量不正确");
    info["goods_number"] = num;

    if (!goods_cat) return reject("商品没有设置所属分类");
    let cats = goods_cat.split(",");
    if (cats.length > 0) {
      info["cat_one_id"] = cats[0];
    }
    if (cats.length > 1) {
      info["cat_two_id"] = cats[1];
    }
    if (cats.length > 2) {
      info["cat_three_id"] = cats[2];
      info["cat_id"] = cats[2];
    }

    if (goods_weight) {
      weight = parseFloat(goods_weight);
      if (isNaN(weight) || weight < 0) return reject("商品重量格式不正确");
      info["goods_weight"] = weight;
    } else {
      info["goods_weight"] = 0;
    }
    if (goods_introduce) {
      info["goods_introduce"] = goods_introduce;
    }

    if (goods_big_logo) {
      info["goods_big_logo"] = goods_big_logo;
    } else {
      info["goods_big_logo"] = "";
    }

    if (goods_small_logo) {
      info["goods_small_logo"] = goods_small_logo;
    } else {
      info["goods_small_logo"] = "";
    }

    if (goods_state) {
      info["goods_state"] = goods_state;
    }

    // 图片
    if (pics) {
      info["pics"] = pics;
    }

    // 属性
    if (attrs) {
      info["attrs"] = attrs;
    }

    info["add_time"] = Date.parse(new Date()) / 1000;
    info["upd_time"] = Date.parse(new Date()) / 1000;
    info["is_del"] = "0";

    if (hot_mumber) {
      hot_num = parseInt(hot_mumber);
      if (isNaN(hot_num) || hot_num < 0) return reject("热销品数量格式不正确");
      info["hot_mumber"] = hot_num;
    } else {
      info["hot_mumber"] = 0;
    }

    info["is_promote"] = info["is_promote"] ? info["is_promote"] : false;

    resolve(info);
  });
}

//检查商品名称是否重复
function checkGoodName(info) {
  return new Promise(function (resolve, reject) {
    DAO.findOne(
      "GoodModel",
      { goods_name: info.goods_name, is_del: "0" },
      function (err, good) {
        if (err) return reject(err);
        if (!good) return resolve(info);
        //修改 校验
        if (good.goods_id == info.goods_id) return resolve(info);
        return reject("商品名称已存在");
      }
    );
  });
}

function createGoodInfo(info) {
  return new Promise((resolve, reject) => {
    DAO.create("GoodModel", info, function (err, good) {
      if (err) return reject("创建商品基本信息失败" + err);
      good.goods_cat = good.getGoodCat();
      info.good = good;
      return resolve(info);
    });
  });
}

function createGoodPic(pic) {
  return new Promise((resolve, reject) => {
    if (!pic) return reject("图片对象不能为空");
    DAO.create("GoodPicModel").create(pic, function (err, newPic) {
      if (err) return reject("创建图片数据失败");
      resolve();
    });
  });
}

/**
 * 裁剪图片
 * @param {*} srcPath 原始路径
 * @param {*} savePath 保存路径
 * @param {*} newWidth
 * @param {*} newHeigh
 */
function clipImage(srcPath, savePath, newWidth, newHeigh) {
  return new Promise((resolve, reject) => {
    const readable = fs.createReadStream(srcPath);
    const writable = fs.createWriteStream(savePath);
    readable.pipe(writable);
    readable.on("end", function (err) {
      resolve();
    });
  });
}

//删除图片
function removeGoodPic(pic) {
  return new Promise((resolve, reject) => {
    // DAO.delete("GoodPicModel", pic.pics_id, function(err, cb) {
    //     if(err) return reject(err);
    //     resolve();
    // })
    if (!pic || !pic.remove) return reject("删除商品图片记录失败");
    pic.remove((err) => {
      if (err) return reject("删除失败");
      resolve();
    });
  });
}

function removeGoodPicFile(path) {
  return new Promise((resolve, reject) => {
    fs.unlink(path, function (err) {
      if (err) return reject(err);
      resolve();
    });
  });
}

function updateGoodPics(info) {
  return new Promise((resolve, reject) => {
    if (!info.good.goods_id) return reject("更新商品图片失败");
    if (!info.pics) return resolve(info);
    DAO.list(
      "GoodPicModel",
      { columns: { goods_id: info.good.goods_id } },
      function (err, oldpics) {
        if (err) return reject("获取商品图片列表失败");
        const batchFn = [];
        const newPics = info.pics ? info.pics : [];
        const newPicsBK = keyBy(newPics, "pics_id");
        let addNewPics = (reserveOldPics = delOldPics = []);
        oldpics.forEach(function (pic) {
          if (newPicsBK[pic.pics_id]) {
            reserveOldPics.push(pic);
          } else {
            delOldPics.push(pic);
          }
        });
        addNewPics.forEach(pic, function (pic) {
          if (!pic.pics_id && pic.pic) {
            newPicsBK.push(pic);
          }
        });
        //处理分类图片

        oldpics.forEach(function (pic) {
          //删除物理路径
          batchFn.push(
            removeGoodPicFile(path.join(process.cwd(), pic.pics_big))
          );
          batchFn.push(
            removeGoodPicFile(path.join(process.cwd(), pic.pics_mid))
          );
          batchFn.push(
            removeGoodPicFile(path.join(process.cwd(), pic.pics_sma))
          );
          //删除数据库数据
          batchFn.push(removeGoodPic(pic));
        });

        addNewPics.forEach(function (pic) {
          const src = path.join(process.cwd(), pic.pic);
          //pic: "tmp_uploads\\933df948d7d2df5967147b0f163c09b7.png"
          // 'foo/bar/baz'.split(path.sep);
          // Returns: ['foo', 'bar', 'baz']
          const tmp = src.split(path.sep);
          const filename = tmp[tmp.length - 1];
          // 裁剪
          pic.pics_big = "uploads/goodspics/big_" + filename;
          pic.pics_mid = "uploads/goodspics/mid_" + filename;
          pic.pics_sma = "uploads/goodspics/sma_" + filename;
          batchFn.push(
            clipImage(src, path.join(process.cwd(), pic.pics_big), 800, 800)
          );
          batchFn.push(
            clipImage(src, path.join(process.cwd(), pic.pics_mid), 400, 400)
          );
          batchFn.push(
            clipImage(src, path.join(process.cwd(), pic.pics_sma), 200, 200)
          );
          pic.goods_id = info.good.goods_id;

          // 数据库新建记录
          batchFn.push(createGoodPic(pic));
        });

        if (batchFn.length === 0) {
          return resolve(info);
        }
        //批量执行
        Promise.all(batchFn)
          .then(() => {
            resolve(info);
          })
          .catch((err) => {
            if (err) return reject(err);
          });
      }
    );
  });
}

function createGoodAttribute(goodAttribute) {
  return new Promise((resolve, reject) => {
    DAO.create(
      "GoodAttributeModel",
      omit(goodAttribute, "delete_time"),
      function (err, newAttr) {
        if (err) return reject("创建商品参数失败");
        resolve(newAttr);
      }
    );
  });
}

//更新商品属性
function updateGoodAttributes(info) {
  return new Promise((resolve, reject) => {
    const good = info.good;
    if (!good.goods_id) return reject("获取商品图片必须先获取商品信息");
    if (!info.attrs) return resolve(info);
    GoodsAttributeDAO.clearGoodAttributes(good.goods_id, function (err) {
      if (err) return reject("清理原始商品的参数失败");
      const newAttrs = info.attrs ? info.attrs : [];
      const createFn = [];
      newAttrs.forEach(function (attr) {
        attr.goods_id = good.goods_id;
        if (attr.attr_value) {
          if (attr.attr_value instanceof Array) {
            attr.attr_value = attr.attr_value.join(",");
          } else {
            attr.attr_value = attr.attr_value;
          }
        } else {
          attr.attr_value = "";
        }
        createFn.push(createGoodAttribute(clone(attr)));
      });

      if (createFn.length == 0) return resolve(info);

      Promise.all(createFn)
        .then(function () {
          resolve(info);
        })
        .catch(function (error) {
          if (error) return reject(error);
        });
    });
  });
}

//获取图片
function getAllPics(info) {
  return new Promise((resolve, reject) => {
    if (!info.good.goods_id) return reject("获取商品图片必须先获取商品信息");
    DAO.list(
      "GoodPicModel",
      { columns: { goods_id: info.good.goods_id } },
      function (err, goodPics) {
        if (err) return reject("获取所有商品图片列表失败");
        goodPics.forEach(function (pic) {
          if (
            pic.pics_big.startsWith("http") ||
            pic.pics_mid.startsWith("http") ||
            pic.pics_sma.startsWith("http")
          ) {
            //外部爬取图片
            pic.pics_big_url = pic.pics_big;
            pic.pics_mid_url = pic.pics_mid;
            pic.pics_sma_url = pic.pics_sma;
          } else {
            pic.pics_big_url = upload_config.get("baseURL") + pic.pics_big;
            pic.pics_mid_url = upload_config.get("baseURL") + pic.pics_mid;
            pic.pics_sma_url = upload_config.get("baseURL") + pic.pics_sma;
          }
        });
        info.good.pics = goodPics;
        resolve(info);
      }
    );
  });
}

//获取对应商品属性
function getAllAttrs(info) {
  return new Promise((resolve, reject) => {
    if (!info.good.goods_id) return reject("获取商品图片必须先获取商品信息");
    GoodsAttributeDAO.list(info.good.goods_id, function (err, goodAttrs) {
      if (err) return reject("获取所有商品参数列表失败");
      info.good.attrs = goodAttrs;
      resolve(info);
    });
  });
}

//新增
module.exports.createGood = function (params, cb) {
  // 参数验证
  generateGoodInfo(params)
    //检查商品名称
    .then(checkGoodName)
    //   创建商品
    .then(createGoodInfo)
    //更新商品图片
    .then(updateGoodPics)
    //更新商品参数
    .then(updateGoodAttributes)
    .then(getAllPics)
    .then(getAllAttrs)
    .then(function (info) {
      cb(null, info.good);
    })
    .catch(function (err) {
      cb(err);
    });
};
